package com.dews.information.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dews.common.constant.HttpStatus;
import com.dews.common.core.domain.TreeSelect;
import com.dews.common.core.page.TableDataInfo;
import com.dews.common.exception.ServiceException;
import com.dews.information.convert.SubjectConvert;
import com.dews.information.domain.dto.SubjectQueryDTO;
import com.dews.information.domain.dto.SubjectSaveDTO;
import com.dews.information.domain.dto.SubjectUpdateDTO;
import com.dews.information.domain.entity.Subject;
import com.dews.information.domain.vo.SubjectVo;
import com.dews.information.mapper.SubjectMapper;
import com.dews.information.service.ISubjectService;
import com.dews.system.domain.SysDept;
import com.dews.system.domain.SysUser;
import com.dews.system.mapper.SysUserMapper;
import com.dews.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 专业Service业务层处理
 *
 * @author qingfeng
 * @date 2024-11-15
 */
@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements ISubjectService {

    private SubjectMapper subjectMapper;
    private ISysDeptService sysDeptService;
    private SysUserMapper sysUserMapper;

    @Autowired
    public SubjectServiceImpl(SubjectMapper subjectMapper,
                              ISysDeptService sysDeptService,
                              SysUserMapper sysUserMapper) {
        this.subjectMapper = subjectMapper;
        this.sysDeptService = sysDeptService;
        this.sysUserMapper = sysUserMapper;
    }


    /**
     * 查询专业列表
     *
     * @param subjectQueryDTO 主题查询 DTO
     * @return 专业
     */
    @Override
    public TableDataInfo selectSubjectList(SubjectQueryDTO subjectQueryDTO) {
        Page<Subject> subjectPage = this.page(
                new Page<Subject>(subjectQueryDTO.getPageNum(), subjectQueryDTO.getPageSize()),
                Wrappers.<Subject>lambdaQuery()
                        .eq(ObjectUtil.isNotNull(subjectQueryDTO.getDepId()), Subject::getDepId, subjectQueryDTO.getDepId())
                        .like(StrUtil.isNotBlank(subjectQueryDTO.getSubjectName()), Subject::getSubjectName, subjectQueryDTO.getSubjectName())
                        .eq(ObjectUtil.isNotNull(subjectQueryDTO.getIsEnable()), Subject::getIsEnable, subjectQueryDTO.getIsEnable())
        );
        if (CollUtil.isEmpty(subjectPage.getRecords())) {
            return TableDataInfo.builder()
                    .code(HttpStatus.SUCCESS)
                    .msg("查询成功")
                    .rows(Collections.emptyList())
                    .total(subjectPage.getTotal())
                    .build();
        }
        // 封装部门名称
        Map<Long, String> depMap = sysDeptService.selectByIds(
                        subjectPage.getRecords()
                                .stream()
                                .map(Subject::getDepId)
                                .collect(Collectors.toSet())
                ).stream()
                .collect(Collectors.toMap(
                        SysDept::getDeptId,
                        SysDept::getDeptName
                ));
        // 查询用户信息
        Map<Long, String> userMap = sysUserMapper.selectBatchIds(
                        subjectPage.getRecords()
                                .stream()
                                .map(Subject::getDirectorId)
                                .collect(Collectors.toSet())
                ).stream()
                .collect(Collectors.toMap(
                        SysUser::getUserId,
                        SysUser::getUserName
                ));
        return TableDataInfo.builder()
                .code(HttpStatus.SUCCESS)
                .msg("查询成功")
                .rows(subjectPage.getRecords()
                        .stream()
                        .map(subject -> {
                            SubjectVo subjectVo = SubjectConvert.INSTANCE.convert(subject);
                            subjectVo.setDepName(depMap.get(subject.getDepId()));
                            subjectVo.setDirectorName(userMap.get(subject.getDirectorId()));
                            return subjectVo;
                        })
                        .collect(Collectors.toList())
                )
                .total(subjectPage.getTotal())
                .build();
    }

    /**
     * 查询专业
     *
     * @param id 专业主键
     * @return 专业
     */
    @Override
    public Subject selectSubjectById(Integer id) {
        return subjectMapper.selectById(id);
    }

    /**
     * 新增专业
     *
     * @param subjectSaveDTO 主题保存 DTO
     * @return 结果
     */
    @Override
    public int insertSubject(SubjectSaveDTO subjectSaveDTO) {
        Subject subject = SubjectConvert.INSTANCE.convert(subjectSaveDTO);
        checkData(subject);
        return baseMapper.insert(subject);

    }

    /**
     * 修改专业
     *
     * @param subjectUpdateDTO 主题更新 DTO
     * @return 结果
     */
    @Override
    public int updateSubject(SubjectUpdateDTO subjectUpdateDTO) {
        Subject subject = SubjectConvert.INSTANCE.convert(subjectUpdateDTO);
        checkData(subject);
        return baseMapper.updateById(subject);
    }

    private void checkData(Subject subject) {
        // 校验专业名不能重复
        List<Subject> subjectList = subjectMapper.selectList(
                Wrappers.<Subject>lambdaQuery()
                        .and(wrapper ->
                                wrapper.eq(Subject::getSubjectCode, subject.getSubjectCode())
                                        .or()
                                        .eq(Subject::getSubjectName, subject.getSubjectName())
                        )
                        .ne(ObjectUtil.isNotNull(subject.getId()), Subject::getId, subject.getId())
        );
        if (CollUtil.isNotEmpty(subjectList)) {
            throw new ServiceException("专业名称或代码重复");
        }
    }

    /**
     * 批量删除专业
     *
     * @param ids 需要删除的专业主键
     * @return 结果
     */
    @Override
    public int deleteSubjectByIds(List<Integer> ids) {
        return subjectMapper.deleteByIds(ids);
    }

    /**
     * 删除专业信息
     *
     * @param id 专业主键
     * @return 结果
     */
    @Override
    public int deleteSubjectById(Integer id) {
        return subjectMapper.deleteById(id);
    }

    @Override
    public List<TreeSelect> getSubjectTree() {
        // 封装部门名称
        Map<Long, String> depMap = sysDeptService.list()
                .stream()
                .collect(Collectors.toMap(
                        SysDept::getDeptId,
                        SysDept::getDeptName
                ));
        return baseMapper.selectList(Wrappers.<Subject>lambdaQuery().eq(Subject::getIsEnable, 1))
                .stream()
                .collect(Collectors.groupingBy(Subject::getDepId))
                .entrySet()
                .stream()
                .map(e -> TreeSelect.builder()
                        .id(e.getKey())
                        .label(depMap.getOrDefault(e.getKey(), ""))
                        .children(
                                e.getValue()
                                        .stream()
                                        .map(subject -> TreeSelect.builder()
                                                .id(Long.valueOf(subject.getId()))
                                                .label(subject.getSubjectName())
                                                .build())
                                        .collect(Collectors.toList())
                        )
                        .build()
                )
                .collect(Collectors.toList());
    }

}
